From 52869aa3f3dbc8cac6f8391c70bb3e8d85cae729 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Mon, 5 Jun 2006 00:56:33 +0000 Subject: [PATCH] speed up GEGL --- ChangeLog | 5 + extensions/gegl-fixups.c | 402 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 407 insertions(+) create mode 100644 extensions/gegl-fixups.c diff --git a/ChangeLog b/ChangeLog index 0b5a290..dafe5b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-06-05 Øyvind Kolås + + * extensions/gegl-fixups.c: A babl extension to make the testing of + gegl faster. + 2006-06-02 Øyvind Kolås * extensions/gggl.c: (table_init): Fix some compile warnings. diff --git a/extensions/gegl-fixups.c b/extensions/gegl-fixups.c new file mode 100644 index 0000000..556dbac --- /dev/null +++ b/extensions/gegl-fixups.c @@ -0,0 +1,402 @@ +/* + * This file was part of gggl, it implements a variety of pixel conversion + * functions that are usable with babl, the file needs more cleanup, and + * doesn't return the number of samples processed as a long, like it's supposed to. + * + * GGGL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GGGL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GGGL; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Rights are granted to use this shared object in libraries covered by + * LGPL. (exception added, during import into babl CVS.) + * + * Copyright 2003, 2004, 2005 Øyvind Kolås + */ + +#include "babl.h" + +#define INLINE inline + +#include +#include +#include + +/* + * Implemented according to information read from: + * + * http://www.cinenet.net/~spitzak/conversion/sketches_0265.pdf + * + * initially ignoring any diffusion, to keep the implementation + * smaller, and interchangeable with the non optimized version. + * + * due to ability to be able to relicence gggl under a different + * licence than GPL, I avoided the temptation to look at the + * source files in the same location, in case I was going to + * need this piece of code for projects where GPL compatibility + * was a must. + * + * TODO: error diffusion, + * gamma correction (not really,. gamma correction belongs in seperate ops,. + */ + + +/* lookup tables used in conversion */ + +static float table_8_F[1 << 8]; +static float table_8g_F[1 << 8]; +static unsigned char table_F_8[1 << 16]; +static unsigned char table_F_8g[1 << 16]; + + +static int table_inited = 0; + +static void +table_init (void) +{ + if (table_inited) + return; + table_inited = 1; + + /* fill tables for conversion from integer to float */ + { + int i; + for (i = 0; i < 1 << 8; i++) + { + float direct = i/255.0; + table_8_F[i] = direct; + table_8g_F[i] = pow(direct, 2.2F); + } + } + /* fill tables for conversion from float to integer */ + { + union + { + float f; + unsigned short s[2]; + } u; + u.f = 0.0; + + u.s[0] = 0.0; + + for (u.s[1] = 0; u.s[1] < 65535; u.s[1] += 1) + { + unsigned char c; + unsigned char cg; + + if (u.f <= 0.0) + { + c = 0; + cg = 0; + } + else if (u.f >= 1.0) + { + c = 255; + cg = 255; + } + else + { + c = rint (u.f * 255.0); + cg = rint (pow(u.f,2.2F) * 255.0); + } + + table_F_8[u.s[1]] = c; + table_F_8g[u.s[1]] = cg; + } + } + /* fix tables to ensure 1:1 conversions back and forth */ + if (0) + { + int i; + for (i = 0; i < 256; i++) + { + float f = table_8_F[i]; + unsigned short *hi = ((unsigned short *)(void*) &f); + unsigned short *lo = ((unsigned short *)(void*) &f); + *lo = 0; + table_F_8[(*hi)] = i; + } + } +} + +/* function to find the index in table for a float */ +static unsigned int +gggl_float_to_index16 (float f) +{ + union + { + float f; + unsigned short s[2]; + } u; + u.f = f; + return u.s[1]; +} + +static INLINE long +conv_F_8 (unsigned char *src, unsigned char *dst, long samples) +{ + if (!table_inited) + table_init (); + long n=samples; + while (n--) + { + register float f = (*(float *) src); + *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)]; + dst += 1; + src += 4; + } + return samples; +} + +static INLINE long +conv_8_F (unsigned char *src, unsigned char *dst, long samples) +{ + if (!table_inited) + table_init (); + long n=samples; + while (n--) + { + (*(float *) dst) = table_8_F[*(unsigned char *) src]; + dst += 4; + src += 1; + } + return samples; +} + + +static INLINE long +conv_rgbaF_rgb8 (unsigned char *src, unsigned char *dst, long samples) +{ + long n=samples; + while (n--) + { + register float f = (*(float *) src); + *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)]; + src += 4; + dst += 1; + + f = (*(float *) src); + *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)]; + src += 4; + dst += 1; + + f = (*(float *) src); + *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)]; + src += 4; + dst += 1; + + src += 4; + + } + return samples; +} + + +/*********/ +static INLINE long +conv_rgbaF_rgba8 (unsigned char *src, unsigned char *dst, long samples) +{ + conv_F_8 (src, dst, samples * 4); + return samples; +} + +#define conv_rgbaF_rgbP8 conv_rgbaF_rgba8 + +static INLINE long +conv_rgbF_rgb8 (unsigned char *src, unsigned char *dst, long samples) +{ + conv_F_8 (src, dst, samples * 3); + return samples; +} + +static INLINE long +conv_gaF_ga8 (unsigned char *src, unsigned char *dst, long samples) +{ + conv_F_8 (src, dst, samples * 2); + return samples; +} + +#define conv_rgbAF_rgbA8 conv_rgbaF_rgba8 +#define conv_gF_g8 conv_F_8 +#define conv_gAF_gA8 conv_gaF_ga8 + + +static INLINE long +conv_rgba8_rgbaF (unsigned char *src, unsigned char *dst, long samples) +{ + long n=samples; + while (n--) + { + (*(float *) dst) = table_8g_F[*(unsigned char *) src]; + dst += 4; + src += 1; + + (*(float *) dst) = table_8g_F[*(unsigned char *) src]; + dst += 4; + src += 1; + + (*(float *) dst) = table_8g_F[*(unsigned char *) src]; + dst += 4; + src += 1; + + (*(float *) dst) = table_8_F[*(unsigned char*) src]; + dst += 4; + src += 1; + } + return samples; +} + +static INLINE long +conv_rgb8_rgbaF (unsigned char *src, unsigned char *dst, long samples) +{ + long n=samples; + while (n--) + { + (*(float *) dst) = table_8g_F[*(unsigned char *) src]; + dst += 4; + src += 1; + + (*(float *) dst) = table_8g_F[*(unsigned char *) src]; + dst += 4; + src += 1; + + (*(float *) dst) = table_8g_F[*(unsigned char *) src]; + dst += 4; + src += 1; + + (*(float *) dst) = 1.0; + dst += 4; + } + return samples; +} + +static long +conv_rgbAF_sdl32 (unsigned char *srcc, + unsigned char *dstc, + long samples) +{ + float *src = (void*)srcc; + unsigned char *dst = (void*)dstc; + long n=samples; + while (n--) + { + int i; + float alpha = src[3]; + if (alpha < 0.0001) + alpha = 0.0001; + for (i=0;i<3;i++) + { + float ca=src[i]; + float c; + int ret; + c=ca/alpha; + if (alpha==0.0) + ret=0; + else + ret = table_F_8g[gggl_float_to_index16 (c)]; + if (ret<=0) + dst[i]=0; + else if (ret>255) + dst[i]=255; + else + dst[i] = ret; + } + { + int t=dst[0]; + dst[0]=dst[2]; + dst[2]=t; + dst[3]=255; + } + src += 4; + dst += 4; + } + return samples; +} + + +static long +conv_rgbaF_sdl32 (unsigned char *srcc, + unsigned char *dstc, + long samples) +{ + float *src = (void*)srcc; + unsigned char *dst = (void*)dstc; + long n=samples; + while (n--) + { + dst[0] = table_F_8g[gggl_float_to_index16 (src[2])]; + dst[1] = table_F_8g[gggl_float_to_index16 (src[1])]; + dst[2] = table_F_8g[gggl_float_to_index16 (src[0])]; + src += 4; + dst += 4; + } + return samples; +} + +#define conv_rgb8_rgbAF conv_rgb8_rgbaF + +int +init (void) +{ + Babl *rgbaF = babl_format_new ( + babl_model ("RGBA"), + babl_type ("float"), + babl_component ("R"), + babl_component ("G"), + babl_component ("B"), + babl_component ("A"), + NULL); + Babl *rgbAF = babl_format_new ( + babl_model ("RaGaBaA"), + babl_type ("float"), + babl_component ("Ra"), + babl_component ("Ga"), + babl_component ("Ba"), + babl_component ("A"), + NULL); + Babl *rgba8 = babl_format_new ( + babl_model ("R'G'B'A"), + babl_type ("u8"), + babl_component ("R'"), + babl_component ("G'"), + babl_component ("B'"), + babl_component ("A"), + NULL); + Babl *rgb8 = babl_format_new ( + babl_model ("R'G'B'"), + babl_type ("u8"), + babl_component ("R'"), + babl_component ("G'"), + babl_component ("B'"), + NULL); + Babl *sdl32 = babl_format_new ( + babl_model ("R'G'B'"), + babl_type ("u8"), + babl_component ("B'"), + babl_component ("G'"), + babl_component ("R'"), + babl_component ("PAD"), + NULL); + + table_init (); + +#define o(src,dst) \ + babl_conversion_new (src, dst, "linear", conv_##src##_##dst, NULL) + + o (rgb8, rgbaF); + o (rgb8, rgbAF); + o (rgba8, rgbaF); + o (rgbaF, sdl32); + o (rgbAF, sdl32); + + return 0; +} -- 2.30.2